package cn.bonoon.handler.impl;

import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;

import cn.bonoon.core.ILoginEditor;
import cn.bonoon.kernel.exceptions.PasswordVerifierException;
import cn.bonoon.kernel.support.PasswordVerifier;
import cn.bonoon.kernel.support.entities.EntityLoginable;
import cn.bonoon.kernel.util.MD5Util;
import cn.bonoon.kernel.util.StringHelper;

/**
 * 这里主要是对{@link PasswordEncoder}进行封闭
 * @author jackson
 *
 */
public class PasswordVerifierImpl implements PasswordVerifier{
	
	@Autowired
	private PasswordEncoder passwordEncoder;
	
	@Override
	public void setPassword(EntityLoginable entity, String pwd, String repwd)throws PasswordVerifierException {
//		if(null == entity) throw new PasswordVerifierException("找不到该用户！");
		entity.setLoginPwd(_verify(pwd, repwd, null));
	}
	
	@Override
	public void setLoginName(EntityLoginable entity, String loginName) throws PasswordVerifierException {
//		if (null == entity)
//			throw new PasswordVerifierException("找不到该用户！");
		entity.setLoginName(_verify(loginName));
	}
	
	@Override
	public void set(EntityLoginable entity, ILoginEditor editor) throws PasswordVerifierException {
//		if(null == entity) throw new PasswordVerifierException("找不到该用户！");
		entity.setLoginPwd(_verify(editor.getLoginPwd(), editor.getConfimPwd(), null));
		entity.setLoginName(_verify(editor.getLoginName()));
	}

	@Override
	public String randomPassword(EntityLoginable entity)throws PasswordVerifierException {
//		if(null == entity) throw new PasswordVerifierException("找不到该用户！");
		String pwd = MD5Util.randomMD5String().substring(2, 10);
		entity.setLoginPwd(passwordEncoder.encode(MD5Util.getMD5(pwd)));
		return pwd;
	}

	@Override
	public void resetPassword(EntityLoginable entity, String oldPwd, String newPwd, String repwd)throws PasswordVerifierException {
		
		String oldPassword = entity.getLoginPwd();
		assertPassword(StringHelper.isEmpty(oldPwd), "请输入旧密码！");
		assertPassword(!passwordEncoder.matches(oldPwd, oldPassword), "旧密码不正确，请重新输入旧密码！");
		
		String md5npwd = MD5Util.getMD5(newPwd);
		String newPassword = _verify(newPwd, repwd, md5npwd);
		assertPassword(passwordEncoder.matches(newPwd, oldPassword), "不允许新密码与旧密码设置成一样，请重新输入！");
		
		entity.setLoginPwd(newPassword);
	}
	//private final Pattern pattern = Pattern.compile("^[a-zA-Z0-9~!@#$%^&*-]{6,20}$");
	// 删除  js已经经过了MD5加密，所以这里没法判断是否符合条件
	
	@Value("${user.password.pattern}")
	private String pattern;
	@Value("${user.password.pattern.exception}")
	private String patternException;
	
	@Override
	public String verify(String pwd, String repwd)throws PasswordVerifierException {
		return _verify(pwd, repwd, null);
	}
	
	/**
	 * 
	 * 注意，这里要求传进来的是明文的密码
	 * @param pwd 明文密码
	 * @param repwd 明文密码
	 * @return
	 * @throws PasswordVerifierException
	 */
	private String _verify(String pwd, String repwd, String md5npwd)throws PasswordVerifierException{
		//不允许出现非法字符
		
		// js已经经过了MD5加密，所以这里没法判断是否符合条件
		assertPassword(StringHelper.isEmpty(pwd), "请输入密码！");
		assertPassword(!pwd.equals(repwd), "验证密码不正确！");
		assertPassword(!Pattern.compile(this.pattern).matcher(pwd).matches(), patternException);
		
		if(null == md5npwd) md5npwd = MD5Util.getMD5(pwd);
		return passwordEncoder.encode(md5npwd);
	}
	
	private void assertPassword(boolean error, String msg){
		if(error) throw new PasswordVerifierException(msg);
	}
	
	@Override
	public String checkAndEncode(String pwd) throws PasswordVerifierException {
		
		assertPassword(!Pattern.compile(this.pattern).matcher(pwd).matches(), patternException);
		
		return passwordEncoder.encode(MD5Util.getMD5(pwd));
	}
	
	@Value("${user.loginName.pattern}")
	private String loginNamePattern;
	@Value("${user.loginName.pattern.exception}")
	private String loginNamePatternException;
	
	@Override
	public String verify(String loginName) throws PasswordVerifierException {
		return _verify(loginName);
	}
	
	private String _verify(String loginName)throws PasswordVerifierException{
		assertPassword(StringHelper.isEmpty(loginName), "请输入登录名！");
		assertPassword(!Pattern.compile(this.loginNamePattern).matcher(loginName).matches(), loginNamePatternException);
		return loginName;
	}

	@Override
	public boolean matches(CharSequence rawPassword, String encodedPassword) {
		return passwordEncoder.matches(rawPassword, encodedPassword);
	}

	@Override
	public String encode(CharSequence rawPassword) {
		return passwordEncoder.encode(rawPassword);
	}
}
